package com.ysd.lis.service.impl;


import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.ysd.common.Result;
import com.ysd.lis.dto.SysMenuRoleDto;
import com.ysd.lis.entity.*;
import com.ysd.lis.mapper.sys.SysMenuMapper;
import com.ysd.lis.mapper.sys.SysPointsMapper;
import com.ysd.lis.mapper.sys.SysUserAuthdifferMapper;
import com.ysd.lis.mapper.sys.SysUserMapper;
import com.ysd.lis.request.HandelUserAuthParam;
import com.ysd.lis.request.UserAuthAddParam;
import com.ysd.lis.service.SysUserAuthdifferService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户权限差异表
 * 服务实现类
 * </p>
 *
 * @author LiuQi
 * @since 2023-11-08
 */
@Service
public class SysUserAuthdifferServiceImpl extends ServiceImpl<SysUserAuthdifferMapper, SysUserAuthdiffer> implements SysUserAuthdifferService {

    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private SysMenuMapper sysMenuMapper;
    @Autowired
    private SysPointsMapper sysPointsMapper;
    @Autowired
    private SysUserAuthdifferMapper sysUserAuthdifferMapper;

    public Result getDifferenceSetRoles(HandelUserAuthParam handelUserAuthParam) {
        Map<String, Object> stringObjectMap = finUserAuthDifferListByUserId(handelUserAuthParam.getUserId(), handelUserAuthParam.getRoleId());
        return Result.succ(1, "查询成功", stringObjectMap);
    }

    public Map<String, Object> finUserAuthDifferListByUserId(String userId, String roleId) {
        // 构建返回集合
        Map<String, Object> resultMap = new HashMap<>();
        MPJLambdaWrapper<SysUserAuthdiffer> mpjLambdaWrapper = new MPJLambdaWrapper();
        mpjLambdaWrapper
                .selectAll(SysUserAuthdiffer.class)
                .eq(SysUserAuthdiffer::getUserId, userId);
        if (StringUtils.isNotBlank(roleId)) {
            mpjLambdaWrapper.eq(SysUserAuthdiffer::getRoleId, roleId);
        }
        List<SysUserAuthdiffer> sysUserAuthdiffers = sysUserAuthdifferMapper.selectList(mpjLambdaWrapper);
        // 获取模块数据
        List<SysModule> sysModules = sysUserAuthdiffers.stream().map(sysUserAuthdiffer -> {
            SysModule sysModule = new SysModule();
            sysModule.setId(sysUserAuthdiffer.getModuleId());
            sysModule.setName(sysUserAuthdiffer.getModuleName());
            return sysModule;
        }).collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(sysModule -> sysModule.getId()))), ArrayList::new));
        resultMap.put("modules", sysModules);

        // 获取模块菜单数据
        MPJLambdaWrapper<SysUserAuthdiffer> menuByRoleIdsWrapper = new MPJLambdaWrapper<>();
        menuByRoleIdsWrapper
                .select(SysMenu::getId, SysMenu::getTitle, SysMenu::getParentId, SysMenu::getIcon, SysMenu::getUrl, SysMenu::getModuleId)
                .selectAs(SysUserAuthdiffer::getId, SysMenu::getCreator)
                .leftJoin(SysMenu.class, SysMenu::getId, SysUserAuthdiffer::getFunctionId)
                .eq(SysUserAuthdiffer::getAuthType, "0")
                .eq(SysUserAuthdiffer::getUserId, userId);
        List<SysMenu> SysMenus = sysUserAuthdifferMapper.selectJoinList(SysMenu.class, menuByRoleIdsWrapper);
        if (SysMenus.size() > 0) {
            // 如果详情表中没有一级菜单则 查询出一级菜单
            List<String> parentIds = SysMenus.stream().map(SysMenu::getParentId).collect(Collectors.toList());
            LambdaQueryWrapper<SysMenu> lambdaQueryWrapper1 = new LambdaQueryWrapper();
            lambdaQueryWrapper1.in(SysMenu::getId, parentIds);
            List<SysMenu> sysMenus = sysMenuMapper.selectList(lambdaQueryWrapper1);

            // 查询当前用户下是否有此父级菜单
            LambdaQueryWrapper<SysUserAuthdiffer> lambdaQueryWrapper2 = new LambdaQueryWrapper();
            lambdaQueryWrapper2
                    .eq(SysUserAuthdiffer::getUserId, userId)
                    .in(SysUserAuthdiffer::getFunctionId, parentIds);
            List<SysUserAuthdiffer> sysUserAuthdetails1 = sysUserAuthdifferMapper.selectList(lambdaQueryWrapper2);
            List<String> collected = sysUserAuthdetails1.stream().map(SysUserAuthdiffer::getFunctionId).collect(Collectors.toList());
            List<SysMenu> collect = sysMenus.stream().filter(item -> !collected.contains(item.getId())).collect(Collectors.toList());
            SysMenus.addAll(collect);
            List<SysMenu> returnList = new ArrayList<>();
            SysMenus.stream().forEach(SysMenu -> {
                if (StringUtils.isBlank(SysMenu.getParentId())) {
                    SysMenu.setChildren(getChildren(SysMenu, SysMenus));
                    returnList.add(SysMenu);
                }
            });
            Map<String, List<SysMenu>> moduleMenuMap = returnList.stream().collect(Collectors.groupingBy(SysMenu::getModuleId));
            resultMap.put("moduleMenuMap", moduleMenuMap);
        } else {
            resultMap.put("moduleMenuMap", new HashMap<>());
        }

        // 获取模块功能数据
        Map<String, List<SysPoints>> modulePointMap = sysUserAuthdiffers.stream().filter(item -> "1".equals(item.getAuthType())).map(sysUserAuthdiffer -> {
            SysPoints sysPoints = new SysPoints();
            // 借用sysPoints的Creator字段存储详情id
            sysPoints.setCreator(sysUserAuthdiffer.getId());
            sysPoints.setId(sysUserAuthdiffer.getFunctionId());
            sysPoints.setTitle(sysUserAuthdiffer.getFunctionName());
            sysPoints.setModuleId(sysUserAuthdiffer.getModuleId());
            return sysPoints;
        }).collect(Collectors.groupingBy(SysPoints::getModuleId));
        resultMap.put("modulePointCodeMap", modulePointMap);

        return resultMap;
    }

    public boolean addUserAuthDetails(UserAuthAddParam userAuthAddParam) {
        // 查询用户详细信息
        SysUser SysUser = sysUserMapper.selectById(userAuthAddParam.getUserId());
        List<SysUserAuthdiffer> sysUserAuthdetails = new ArrayList<>();
        // 查询菜单详细信息
        if (userAuthAddParam.getMenus().size() > 0) {
            MPJLambdaWrapper<SysMenu> lambdaQueryWrapper = new MPJLambdaWrapper();
            lambdaQueryWrapper
                    .selectAll(SysMenu.class)
                    .selectAs(SysModule::getName, SysMenuRoleDto::getModuleName)
                    .selectAs(SysModule::getCode, SysMenuRoleDto::getModuleCode)
                    .leftJoin(SysModule.class, SysModule::getId, SysMenu::getModuleId)
                    .eq(SysMenu::getDelFlag, "0")
                    .in(SysMenu::getId, userAuthAddParam.getMenus());
            List<SysMenuRoleDto> sysMenuRoleDtos = sysMenuMapper.selectJoinList(SysMenuRoleDto.class, lambdaQueryWrapper);
            // 添加二级菜单时同时插入二级菜单的父级
            List<String> parentIds = sysMenuRoleDtos.stream().map(SysMenuRoleDto::getParentId).collect(Collectors.toList());
            LambdaQueryWrapper<SysMenu> lambdaQueryWrapper1 = new LambdaQueryWrapper();
            lambdaQueryWrapper1.in(SysMenu::getId, parentIds);
            List<SysMenu> sysMenus = sysMenuMapper.selectList(lambdaQueryWrapper1);
            sysMenus.stream().forEach(item -> {
                SysMenuRoleDto sysMenuRoleDto = new SysMenuRoleDto();
                BeanUtil.copyProperties(item, sysMenuRoleDto);
                sysMenuRoleDtos.add(sysMenuRoleDto);
            });
            sysUserAuthdetails.addAll(getSysUserAuthdetailByMenu(SysUser, sysMenuRoleDtos, "0"));
        }
        // 查询功能详细信息
        if (userAuthAddParam.getPoints().size() > 0) {
            MPJLambdaWrapper<SysPoints> lambdaQueryWrapper1 = new MPJLambdaWrapper();
            lambdaQueryWrapper1
                    .selectAll(SysPoints.class)
                    .selectAs(SysModule::getName, SysMenuRoleDto::getModuleName)
                    .selectAs(SysModule::getCode, SysMenuRoleDto::getModuleCode)
                    .leftJoin(SysModule.class, SysModule::getId, SysPoints::getModuleId)
                    .eq(SysPoints::getDelFlag, "0")
                    .in(SysPoints::getId, userAuthAddParam.getPoints());
            List<SysMenuRoleDto> sysPoints = sysPointsMapper.selectJoinList(SysMenuRoleDto.class, lambdaQueryWrapper1);
            List<SysUserAuthdiffer> sysUserAuthdetailByMenu1 = getSysUserAuthdetailByMenu(SysUser, sysPoints, "1");
            sysUserAuthdetails.addAll(sysUserAuthdetailByMenu1);
        }
        List<SysUserAuthdiffer> resultAuthdetails = new ArrayList<>();
        if (StringUtils.isNotBlank(userAuthAddParam.getRoleId())) {
            resultAuthdetails = sysUserAuthdetails.stream().map(item -> {
                item.setRoleId(userAuthAddParam.getRoleId());
                item.setRoleName(userAuthAddParam.getRoleName());
                return item;
            }).collect(Collectors.toList());
        }
        return this.saveBatch(resultAuthdetails);
    }

    public List<SysUserAuthdiffer> getSysUserAuthdetailByMenu(SysUser SysUser, List<SysMenuRoleDto> SysMenus, String authType) {
        List<SysUserAuthdiffer> sysUserAuthdetails = new ArrayList<>();
        SysMenus.stream().forEach(SysMenu -> {
            SysUserAuthdiffer sysUserAuthdiffer = new SysUserAuthdiffer();
            sysUserAuthdiffer.setUserId(SysUser.getId());
            sysUserAuthdiffer.setUserName(SysUser.getRealname());
            sysUserAuthdiffer.setUserCode(SysUser.getUsername());
            sysUserAuthdiffer.setOrgId(SysUser.getOrgId());
            sysUserAuthdiffer.setPassword(SysUser.getPassword());
            sysUserAuthdiffer.setRoleId(SysMenu.getRoleId());
            sysUserAuthdiffer.setRoleCode(SysMenu.getRoleCode());
            sysUserAuthdiffer.setRoleName(SysMenu.getRoleName());
            sysUserAuthdiffer.setModuleId(SysMenu.getModuleId());
            sysUserAuthdiffer.setModuleCode(SysMenu.getModuleCode());
            sysUserAuthdiffer.setModuleName(SysMenu.getModuleName());
            sysUserAuthdiffer.setFunctionId(SysMenu.getId());
            sysUserAuthdiffer.setFunctionName(SysMenu.getTitle());
            if (authType.equals("0")) {
                if (StringUtils.isBlank(SysMenu.getParentId())) {
                    sysUserAuthdiffer.setMenuType("0");
                } else {
                    sysUserAuthdiffer.setMenuType("1");
                }
                sysUserAuthdiffer.setAuthType("0");
            } else {
                sysUserAuthdiffer.setAuthType("1");
            }
            sysUserAuthdetails.add(sysUserAuthdiffer);
        });
        return sysUserAuthdetails;
    }

    public List<SysMenu> getChildren(SysMenu a, List<SysMenu> menuList) {
        List<SysMenu> result = new ArrayList();
        for (SysMenu menu : menuList) {
            if (StringUtils.isBlank(menu.getParentId())) {
                menu.setParentName("");
            }
            if (StringUtils.isNotBlank(menu.getParentId()) && menu.getParentId().equals(a.getId())) {
                menu.setParentName(a.getTitle());
                result.add(menu);
            }
        }
        for (SysMenu menu : result) {
            menu.setChildren(getChildren(menu, menuList));
        }
        if (result.size() == 0) {
            return new ArrayList<>();
        }
        return result;
    }
}
